﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.IO;
//using System.Diagnostics;
//using System.Runtime.InteropServices;
//using System.Threading;
//using OpenTK;
////using OpenTK.Audio.OpenAL;
//using OpenTK.Audio;

//namespace ArtemisTest
//{
//    public class Sound : Component
//    {
//        public Sound(long uid) : base(uid, ComponentType.sound) { }
//    }
    

//    public class SoundSystem : CSystem
//    {
//        int[] _buffers;
//        int[] _sources;
//        int _listener;

//        public SoundSystem(EntitySystem es) : base(es) { }

//        public void LoadSounds(List<string[]> paths)
//        {
//            //IntPtr device = Alc.OpenDevice(null);
//            //AudioContext ac = new AudioContext();
//            //ac.MakeCurrent();

//            //float[] av = new float[3] { 0f, 0f, -1f };

//            //AL.Listener(ALListener3f.Position, 0, 0, 0);
//            //AL.Listener(ALListenerfv.Orientation,ref av);

//            //XRamExtension xr = new XRamExtension();

//            //int soundCount = paths.Count;
//            //Console.WriteLine("loaded sounds = " + soundCount);
//            //_buffers = new int[soundCount];
//            //_buffers = AL.GenBuffers(soundCount);

//            //AudioReader sound = new AudioReader(paths[0][0]);

//            #region test
//AudioContext AC = new AudioContext();
 
//XRamExtension XRam = new XRamExtension( ); // must be instantiated per used Device if X-Ram is desired.
 
//// reserve 2 Handles
//int[] MyBuffers = new int[2]; 
//MyBuffers = AL.GenBuffers( 2); 
 
//// Load a .wav file from disk
//if ( XRam.IsInitialized ) XRam.SetBufferMode( 2,ref MyBuffers[0], XRamExtension.XRamStorage.Hardware  ); // optional

//AudioReader sound = new AudioReader(paths[0][0]);
//AL.BufferData(MyBuffers[0], sound.ReadToEnd());
//if ( AL.GetError() != ALError.NoError )
//{
//   // respond to load error etc.
//}
 
//// Create a sinus waveform through parameters, this currently requires Alut.dll in the application directory
//if ( XRam.IsInitialized ) XRam.SetBufferMode(1, ref MyBuffers[1], XRamExtension.XRamStorage.Hardware ); // optional
//MyBuffers[1] = (int)Alut.CreateBufferWaveform(AlutWaveform.Sine, 500f, 42f, 1.5f);


//int[] MySources = new int[2];
//MySources = AL.GenSources(2); // gen 2 Source Handles

//AL.Source(MySources[0], ALSourcei.Buffer, (int)MyBuffers[0]); // attach the buffer to a source

//AL.SourcePlay(MySources[0]); // start playback
//AL.Source(MySources[0], ALSourceb.Looping, true); // source loops infinitely

//AL.Source(MySources[1], ALSourcei.Buffer, (int)MyBuffers[1]);
//Vector3 Position = new Vector3(1f, 2f, 3f);
//AL.Source(MySources[1], ALSource3f.Position, ref Position);
//AL.Source(MySources[1], ALSourcef.Gain, 0.85f);
//AL.SourcePlay(MySources[1]);

//Console.ReadLine(); // wait for keystroke before exiting

//AL.SourceStop(MySources[0]); // halt playback
//AL.SourceStop(MySources[1]);

//// See next book page how to connect the buffers to sources in order to play them.
 
//// Cleanup on application shutdown
////AL.DeleteBuffers( 2, ref MyBuffers ); // free previously reserved Handles
////AC.Dispose();
            
//            #endregion

//            ////int channels;
//            ////int bitsPerSample;
//            ////int sampleRate;
//            ////for (int i = 0; i < soundCount; i++)
//            ////{
//            ////    byte[] soundData = SoundUtils.LoadWave(File.Open(paths[i][0], FileMode.Open),
//            ////        out channels, out bitsPerSample, out sampleRate);

//            ////    AL.BufferData(_buffers[i],
//            ////        SoundUtils.GetSoundFormat(channels, bitsPerSample),
//            ////        soundData, soundData.Length,sampleRate);
//            ////}
//            ////_sources = new int[2];
//            ////_sources = AL.GenBuffers(_sources.Length);

//            ////background
//            //AL.Source(_sources[0], ALSourceb.Looping,true);
//            //AL.Source(_sources[0], ALSourcef.Gain, 0.3f);
//            //AL.Source(_sources[0], ALSourcef.Pitch, 1.0f);

//            ////Centre
//            //AL.Source(_sources[1], ALSource3f.Position, 0,0,0);
//            //AL.Source(_sources[1], ALSourceb.Looping, false);
//            //AL.Source(_sources[1], ALSourcef.Gain, 0.3f);
//            //AL.Source(_sources[1], ALSourcef.Pitch, 1.0f);

//            //Console.WriteLine("Playing Sound");
//            //PlayMusic(1, 0);
//        }

//        public void PlayMusic(int bufferId, int sourceId)
//        {
//            /*
//             * 
//             * alSourcePlay(source);
//            // check for errors

//            alGetSourcei(source, AL_SOURCE_STATE, &source_state);
//            // check for errors
//            while (source_state == AL_PLAYING) {
//                    alGetSourcei(source, AL_SOURCE_STATE, &source_state);
//            / check for errors
//}
//             * 
//             */


//            //int buffer;
//            //AL.GetSource(_sources[sourceId], ALGetSourcei.Buffer, out buffer);
//            //if (buffer == _buffers[bufferId]) return;
//            //AL.SourceStop(_sources[sourceId]);
//            //AL.Source(_sources[sourceId], ALSourcei.Buffer, _buffers[bufferId]);
//            int sourceState;

//            AL.SourcePlay(_sources[sourceId]);
            
//            AL.GetSource(sourceId, ALGetSourcei.SourceState,out sourceState);

//            while (sourceState == (int)ALSourceState.Playing)
//            {
//                AL.GetSource(sourceId, ALGetSourcei.SourceState, out sourceState);
//            }
//        }

//        public override void Init()
//        {
            
//            LoadSounds(ScriptReader.GetData("sound\\paths.txt"));
//        }

//        public override void PreUpdate(double dt)
//        {

//        }

//        public override void Update(double dt)
//        {
//             // update OpenAL
//             // place listener at camera
//             AL.Listener( ALListener3f.Position,0,0,0);
//             float listenerAngle = 0;
//             float[] directionvect = new float[6];
//             directionvect[0] = (float) Math.Sin(listenerAngle);
//             directionvect[1] = 0;
//             directionvect[2] = (float) Math.Cos(listenerAngle);
//             directionvect[3] = 0;
//             directionvect[4] = 1;
//             directionvect[5] = 0;
//             AL.Listener( ALListenerfv.Orientation, ref directionvect);
//        }

//        public override void PostUpdate(double dt)
//        {

//        }
//    }
//}

using System;
using IrrKlang;
using System.Collections.Generic;

namespace ArtemisTest
{
    public class SoundPlayer : Component
    {
        public List<bool> ReadyToPlay { get; set; }
        public List<bool> ReadyToStop { get; set; }
        public List<bool> Looping { get; set; }

        public SoundPlayer(long uid) : base(uid, ComponentType.sound_player)
        {
            ReadyToPlay = new List<bool>();
            ReadyToStop = new List<bool>();
        }
    }

    public class Sound : Component
    {
        public List<float> Volume { get; set; }
        public List<string> Path { get; set; }

        public Sound(long uid) : base(uid, ComponentType.sound)
        {
            Path = new List<string>();
            Volume = new List<float>();
            //Path.Add(path);
            //Volume.Add(0.5f);
        }
    }

    public class SoundSystem2 : CSystem
    {
        ISoundEngine _engine;

        public override void Init()
        {
            _engine = new ISoundEngine();
            //_engine.SoundVolume = 0.4f;
            //_engine.Play2D("sound\\Battle_Jazz.ogg");
        }

        public void InitSound(ref Sound s, ref SoundPlayer sp, List<string> paths, List<float> volume, List<bool> looping)
        {
            s.Path = paths;
            s.Volume = volume;
            sp.Looping = looping;
            int c = sp.Looping.Count;
            sp.ReadyToPlay = new List<bool>();
            sp.ReadyToStop = new List<bool>();
            for (int i = 0; i < c; i++)
            {
                sp.ReadyToPlay.Add(false);
                sp.ReadyToStop.Add(false);
            }
        }

        public void SetSoundToPlay(ref SoundPlayer sp, int index)
        {
            if (index < sp.Looping.Count)
            {
                sp.ReadyToPlay[index] = true;
            }
        }

        public override void PreUpdate(double dt)
        {
            throw new NotImplementedException();
        }

        public override void Update(double dt)
        {
            var soundList = this.EntitySystem.Components.GetAllComponentsOfType(ComponentType.sound);
            var soundPlayerList = this.EntitySystem.Components.GetAllComponentsOfType(ComponentType.sound_player);
            foreach (KeyValuePair<long, Component> entry in soundList)
            {
                SoundPlayer sp = soundPlayerList[entry.Key] as SoundPlayer;
                Sound s = entry.Value as Sound;
                if (sp.Looping != null)
                for (int i = 0; i < sp.Looping.Count; i++)
                {

                    if (sp.ReadyToStop[i] && !sp.ReadyToPlay[i])
                    {
                        _engine.RemoveSoundSource(s.Path[i]);
                        break;
                    }
                    if (sp.ReadyToPlay[i])
                    {
                        _engine.SoundVolume = s.Volume[i];
                        _engine.Play2D(s.Path[i], sp.Looping[i]);
                        sp.ReadyToPlay[i] = false;
                    }
                }
            }
        }

        public override void PostUpdate(double dt)
        {
            throw new NotImplementedException();
        }

        public SoundSystem2(EntitySystem es, ScriptSystem ss) : base(es,ss) { }
    }
}